# coding: utf-8
from django.db.models import Sum
from stock.models import PbcTradeType, PbcTradeDaily
import json
import re
import datetime


def convert_number(obj_str):
    pattern = re.compile('(\d+)\D')
    number = int(re.search(pattern, obj_str).groups()[0])
    return number


def get_maturity_volume(trade_types, effective_date=None):
    """
    获取过期交易量之和，并将过期交易设置为完成状态
    过期交易（到期未赎回）：交易状态未完成并且过期日期小于生效日期（或当前日期）
    """
    if effective_date is None:
        current_date = datetime.datetime.now().date()
    else:
        current_date = effective_date
    pbc_maturity_data = PbcTradeDaily.objects.filter(
        type__in=trade_types, status=False, maturity_date__lte=current_date).aggregate(volume_sum=Sum('volume'))
    PbcTradeDaily.objects.filter(
        type__in=trade_types, status=False, maturity_date__lte=current_date).update(status=True)
    # print("过期交易量之和：{}".format(pbc_maturity_data['volume_sum']))
    if pbc_maturity_data['volume_sum'] is None:
        # print("get_maturity_volume返回值为0")
        return 0
    return pbc_maturity_data['volume_sum']


def get_previous_amount(trade_types, effective_date=None):
    """
    获取前一个交易日的实际金额（amount）
    """
    if effective_date is None:
        current_date = datetime.datetime.now().date()
    else:
        current_date = effective_date
    try:
        previous_amount = PbcTradeDaily.objects.filter(type__in=trade_types, effective_date__lt=current_date).order_by('-effective_date').values('amount')[0]
        return previous_amount['amount']
    except IndexError as e:
        print(e)
        # 设定初始金额量值为1000
        return 1000


def calculate_maturity_date(effective_date, maturity_days):
    """
    计算过期日期
    :param effective_date:生效日期
    :param maturity_days: 过期天数
    :return:
    """
    effective_date = datetime.datetime.strptime(effective_date, "%Y-%m-%d")
    maturity_date = effective_date + datetime.timedelta(days=maturity_days)
    maturity_date = maturity_date.strftime("%Y-%m-%d")
    return maturity_date


def convert_maturity_days(maturity):
    """
    转换到期天数，将到期字符串转换为数字（1年=365天）
    :param maturity: 到期字符串（n天/n年）
    :return:
    """
    if maturity.endswith('年'):
        num = int(maturity.strip('').rstrip('年'))
        maturity_days = num * 365
    else:
        maturity_days = int(maturity.strip('').rstrip('天'))
    return maturity_days


def insert_database(content, trade_type, effective_date, insert_obj=None):
    """
    添加数据到数据库
    :param content: 主体文本
    :param trade_type: 类型
    :param effective_date: 生效日期
    :param insert_obj: 数据列表对象，为空时表示没有数据列表
    :return:
    """
    if trade_type.id in (1, 2, 3):
        trade_types = PbcTradeType.objects.filter(id__in=(1, 2, 3))
    else:
        trade_types = [trade_type]

    maturity_volume = get_maturity_volume(trade_types, effective_date)
    previous_amount = get_previous_amount(trade_types, effective_date)

    if insert_obj is None:
        amount = previous_amount - maturity_volume

        PbcTradeDaily.objects.create(
            content=content,
            type=trade_type,
            amount=amount,
            volume=0,
            effective_date=effective_date,
            maturity_days=0,
            maturity_date=effective_date,
            status=True,
            rate=0
        )
    else:
        if len(insert_obj) > 1:
            # 一天有多次交易的情况（如当天同时有7天逆回购和14天逆回购）
            today_volume = 0
            for item in insert_obj:
                today_volume += convert_number(item["volume"])
        else:
            today_volume = convert_number(insert_obj[0]["volume"])

        for item in insert_obj:
            maturity_days = convert_maturity_days(item["maturity"])  # 将字符串到期天数转换为数字
            maturity_date = calculate_maturity_date(effective_date, maturity_days)
            volume = convert_number(item["volume"])
            amount = previous_amount + today_volume - maturity_volume
            rate = item["rate"]

            PbcTradeDaily.objects.create(
                content=content,
                type=trade_type,
                amount=amount,
                volume=volume,
                effective_date=effective_date,
                maturity_days=maturity_days,
                maturity_date=maturity_date,
                status=False,
                rate=rate
            )


def insert_one_pbctrade(trade_data):
    ZoomP = trade_data['ZoomP']
    DateTime = trade_data['DateTime']
    ReverseRepo = trade_data['ReverseRepo']
    MLF = trade_data['MLF']
    TMLF = trade_data['TMLF']
    Other = trade_data['Other']
    effective_date = datetime.datetime.strptime(DateTime, "%Y-%m-%d %H:%M:%S").date().strftime("%Y-%m-%d")

    if (len(ReverseRepo)+len(MLF)+len(TMLF)+len(Other)) == 0 and "较高水平" in trade_data["ZoomP"]:
        trade_type = PbcTradeType.objects.get(id=2)  # 处于较高水平，不开展逆回购
        insert_database(ZoomP, trade_type, effective_date)
    elif (len(ReverseRepo)+len(MLF)+len(TMLF)+len(Other)) == 0 and "逆回购" in trade_data["ZoomP"]:
        trade_type = PbcTradeType.objects.get(id=1)  # 处于合理水平，不开展逆回购
        insert_database(ZoomP, trade_type, effective_date)
    else:
        if len(ReverseRepo) != 0:
            trade_type = PbcTradeType.objects.get(id=3)    # 开展逆回购操作
            insert_database(ZoomP, trade_type, effective_date, ReverseRepo)
        if len(MLF) != 0:
            trade_type = PbcTradeType.objects.get(id=4)    # 中期借贷便利（MLF）
            insert_database(ZoomP, trade_type, effective_date, MLF)
        if len(TMLF) != 0:
            trade_type = PbcTradeType.objects.get(id=5)    # 定向中期借贷便利（TMLF）
            insert_database(ZoomP, trade_type, effective_date, TMLF)


def main():
    with open('public/backup_data/news.20200824_v2.json', 'r', encoding='utf-8') as f:
        items = json.loads(f.read())
    for item in reversed(items):
        print(item['DateTime'])
        insert_one_pbctrade(item)


if __name__ == '__main__':
    main()
